#ifndef FORMAT
#define FORMAT

#include <mutex>
#include <memory>
#include "tools.h"
#include "parameter_manager.h"

namespace lcf
{

    struct XRational
    {
        int num; // Numerator
        int den; // Denominator
    };

    // 封装和解封装基类
    class Format
    {
    public:
        Format() : timeOutMs_(0),
                   lastTime_(0),
                   isConnected_(false),
                   context_(nullptr),
                   videoIndex_(0),
                   audioIndex_(1),
                   videoTimeBase_({1, 25}),
                   audioTimeBase_({1, 9000}),
                   videoCodecId_(0)
        {
        }

        ~Format() {}

        // 复制参数 线程安全
        bool CopyPara(int streamIndex, AVCodecParameters *dts);
        // bool CopyPara(int stream_index, AVCodecContext *dts);

        // 返回智能指针 复制视频参数
        std::shared_ptr<ParameterManager> CopyVideoPara();
        std::shared_ptr<ParameterManager> CopyAudioPara();

        /// 设置上下文，并且清理上次的设置的值，如果传递NULL，相当于关闭上下文3
        void SetContext(AVFormatContext *context);

        int AudioIndex() { return audioIndex_; }
        int VideoIndex() { return videoIndex_; }
        XRational VideoTimeBase() { return videoTimeBase_; }
        XRational AudioTimeBase() { return audioTimeBase_; }
        int VideoCodecId() { return videoCodecId_; }
        bool IsConnected() { return isConnected_; }
        // 判断是否超时
        bool IsTimeout()
        {
            if (NowMs() - lastTime_ > timeOutMs_) // 超时
            {
                lastTime_ = NowMs();
                isConnected_ = false;
                return true;
            }
            return false;
        }

        // 根据timebase换算时间
        bool RescaleTime(AVPacket *pkt, long long offsetPts, XRational timeBase);
        bool RescaleTime(AVPacket *pkt, long long offsetPts, AVRational *timeBase);
        // 把pts dts duration 值转为毫秒
        long long RescaleToMs(long long pts, int index);

        // 设定超时时间
        void SetTimeOutMs(int ms);

    protected:
        int timeOutMs_;            // 超时时间 毫秒
        long long lastTime_;       // 上次接收到数据的时间
        bool isConnected_;         // 是否连接成功
        AVFormatContext *context_; // 封装解封装上下文
        std::mutex mtx_;           // 资源互斥
        int videoIndex_;           // video和audio在stream中索引
        int audioIndex_;
        XRational videoTimeBase_;
        XRational audioTimeBase_;
        int videoCodecId_; // 编码器ID
    };

}

#endif